package com.xqb.modules.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xqb.common.constant.Constants;
import com.xqb.common.core.domain.entity.SysUser;
import com.xqb.common.exception.ServiceException;
import com.xqb.common.utils.DateUtils;
import com.xqb.common.utils.SecurityUtils;
import com.xqb.common.utils.bean.BeanUtils;
import com.xqb.modules.domain.dto.AddOrdRefundApplyDto;
import com.xqb.modules.domain.dto.OrdRefundApplyDto;
import com.xqb.modules.domain.po.OrdOrder;
import com.xqb.modules.domain.po.OrdOrderDetail;
import com.xqb.modules.domain.po.OrdRefundApply;
import com.xqb.modules.domain.vo.OrdRefundApplyVo;
import com.xqb.modules.mapper.OrdOrderDetailMapper;
import com.xqb.modules.mapper.OrdOrderMapper;
import com.xqb.modules.mapper.OrdRefundApplyMapper;
import com.xqb.modules.service.IOrdRefundApplyService;
import com.xqb.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 退款申请Service业务层处理
 *
 * @author xqb
 * @date 2024-10-14
 */
@Service
public class OrdRefundApplyServiceImpl extends ServiceImpl<OrdRefundApplyMapper, OrdRefundApply> implements IOrdRefundApplyService {
    @Autowired
    private OrdRefundApplyMapper ordRefundApplyMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private OrdOrderMapper ordOrderMapper;
    @Autowired
    private OrdOrderDetailMapper ordOrderDetailMapper;

    /**
     * 查询退款申请
     *
     * @param id 退款申请主键
     * @return 退款申请
     */
    @Override
    public OrdRefundApply selectOrdRefundApplyById(Long id) {
        return ordRefundApplyMapper.selectOrdRefundApplyById(id);
    }

    /**
     * 查询退款申请列表
     *
     * @param ordRefundApply 退款申请
     * @return 退款申请
     */
    @Override
    public List<OrdRefundApply> selectOrdRefundApplyList(OrdRefundApply ordRefundApply) {
        return ordRefundApplyMapper.selectOrdRefundApplyList(ordRefundApply);
    }

    /**
     * 新增退款申请
     *
     * @param addOrdRefundApplyDto 退款申请
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertOrdRefundApply(AddOrdRefundApplyDto addOrdRefundApplyDto) {
        OrdOrderDetail ordOrderDetail = ordOrderDetailMapper.selectOrdOrderDetailById(addOrdRefundApplyDto.getOrderDetailId());
        if (ordOrderDetail == null) {
            throw new ServiceException("订单不存在");
        }
        if (ordOrderDetail.getStatus().equals(Constants.ORDER_UNPAY) || ordOrderDetail.getStatus().equals(Constants.ORDER_CLOSE)) {
            throw new ServiceException("订单状态错误");
        }
        OrdOrder ordOrder = ordOrderMapper.selectOrdOrderById(ordOrderDetail.getOrderId());
        OrdRefundApply ordRefundApply = OrdRefundApply.builder()
                .userId(SecurityUtils.getUserId())
                .orderId(ordOrderDetail.getOrderId())
                .orderDetailId(ordOrderDetail.getId())
                .refundAmount(ordOrderDetail.getRealPayAmount())
                .refundReason(addOrdRefundApplyDto.getRefundReason())
                .status(Constants.REFUND_APPROVE)
                .insId(ordOrder.getInsId())
                .build();
        int sum = 0;
        sum += ordRefundApplyMapper.insert(ordRefundApply);
        ordOrderDetail.setRefundStatus(Constants.REFUND_APPROVE);
        ordOrder.setRefundTime(ordRefundApply.getCreateTime());
        //TODO 表不全，未完成
        sum += ordOrderMapper.updateOrdOrder(ordOrder);
        sum += ordOrderDetailMapper.updateOrdOrderDetail(ordOrderDetail);
        return sum;
    }

    /**
     * 修改退款申请
     *
     * @param ordRefundApply 退款申请
     * @return 结果
     */
    @Override
    public int updateOrdRefundApply(OrdRefundApply ordRefundApply) {
        ordRefundApply.setUpdateTime(DateUtils.getNowDate());
        return ordRefundApplyMapper.updateOrdRefundApply(ordRefundApply);
    }

    /**
     * 批量删除退款申请
     *
     * @param ids 需要删除的退款申请主键
     * @return 结果
     */
    @Override
    public int deleteOrdRefundApplyByIds(Long[] ids) {
        return ordRefundApplyMapper.deleteOrdRefundApplyByIds(ids);
    }

    /**
     * 删除退款申请信息
     *
     * @param id 退款申请主键
     * @return 结果
     */
    @Override
    public int deleteOrdRefundApplyById(Long id) {
        return ordRefundApplyMapper.deleteOrdRefundApplyById(id);
    }
    @Override
    public int approveOrdRefundApply(Long id) {
        OrdRefundApply ordRefundApply = new OrdRefundApply();
        ordRefundApply.setId(id);
        ordRefundApply.setStatus(5); // 假设5是同意退款的状态码
        return ordRefundApplyMapper.updateById(ordRefundApply);
    }

    @Override
    public int rejectOrdRefundApply(Long id) {
        OrdRefundApply ordRefundApply = new OrdRefundApply();
        ordRefundApply.setId(id);
        ordRefundApply.setStatus(6); // 假设6是拒绝退款的状态码
        return ordRefundApplyMapper.updateById(ordRefundApply);
    }

    @Override
    public List<OrdRefundApplyVo> selectOrdRefundApplyInstitutionList(OrdRefundApplyDto ordRefundApply) {
        // 如果传入的ordRefundApply对象的insId为空，则使用当前登录用户的机构ID
        if (ordRefundApply.getInsId() == null) {
            // 设置insId为当前登录用户的机构ID
            ordRefundApply.setInsId(SecurityUtils.getLoginUser().getUser().getInsId());
        }

        // 查询符合条件的退款申请列表
        List<OrdRefundApply> ordRefundApplyList = ordRefundApplyMapper.selectInstitutionList(ordRefundApply);

        // 如果没有查询到退款申请记录，则返回空列表
        if (ordRefundApplyList.isEmpty()) {
            return new ArrayList<>();
        }

        // 提取所有不同的用户ID和审批人ID
        List<Long> usrIds = ordRefundApplyList.stream().map(OrdRefundApply::getUserId).distinct().collect(Collectors.toList());
        List<Long> approverIds = ordRefundApplyList.stream().map(OrdRefundApply::getApprover).distinct().collect(Collectors.toList());

        // 将用户ID和审批人ID合并并去重
        Set<Long> usrIdsSet = new HashSet<>(usrIds);
        usrIdsSet.addAll(approverIds);

        // 构建查询用户的LambdaQueryWrapper
        LambdaQueryWrapper<SysUser> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.in(SysUser::getUserId, usrIdsSet);
        userLambdaQueryWrapper.select(SysUser::getUserId, SysUser::getUserName, SysUser::getPhonenumber);

        // 查询用户信息列表
        List<SysUser> sysUserList = sysUserMapper.selectList(userLambdaQueryWrapper);

        // 将用户信息列表转换为Map，方便后续查找
        Map<Long, SysUser> sysUserMap = sysUserList.stream().collect(Collectors.toMap(SysUser::getUserId, sysUser -> sysUser));

        // 初始化结果列表
        List<OrdRefundApplyVo> ordRefundApplyVoList = new ArrayList<>();

        // 遍历查询到的退款申请列表
        for (OrdRefundApply ordRefund : ordRefundApplyList) {
            OrdRefundApplyVo ordRefundApplyVo = new OrdRefundApplyVo();
            // 将OrdRefundApply对象的属性复制到OrdRefundApplyVo对象
            BeanUtils.copyProperties(ordRefund, ordRefundApplyVo);

            // 设置申请人姓名和手机号
            ordRefundApplyVo.setProposerName(sysUserMap.get(ordRefund.getUserId()).getUserName());
            ordRefundApplyVo.setProposerMobile(sysUserMap.get(ordRefund.getUserId()).getPhonenumber());

            // 如果存在审批人，则设置审批人姓名
            if (ordRefund.getApprover() != null) {
                ordRefundApplyVo.setApproverName(sysUserMap.get(ordRefund.getApprover()).getUserName());
            }

            // 如果退款状态为同意，则设置退款成功时间
            if (ordRefund.getStatus().equals(Constants.REFUND_AGREE)) {
                ordRefundApplyVo.setRefundSuccessTime(ordRefund.getFinishTime());
            }

            // 将转换后的OrdRefundApplyVo对象添加到结果列表中
            ordRefundApplyVoList.add(ordRefundApplyVo);
        }

        // 如果指定了手机号，则过滤掉与指定手机号不匹配的申请人手机号
        if (ordRefundApply.getPhoneNumber() != null && !"".equals(ordRefundApply.getPhoneNumber())) {
            ordRefundApplyVoList.removeIf(ordRefundApplyVo -> !ordRefundApplyVo.getProposerMobile().equals(ordRefundApply.getPhoneNumber()));
        }

        // 返回结果列表
        return ordRefundApplyVoList;
    }


    @Override
    public int handleOrdRefundApply(OrdRefundApplyDto ordRefundApplyDto) {
        OrdRefundApply ordRefundApply = new OrdRefundApply();
        BeanUtils.copyProperties(ordRefundApplyDto, ordRefundApply);
        return ordRefundApplyMapper.updateById(ordRefundApply);
    }
}
